/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = ora_ttc7_item.c                                    */
/*  NOTE      =                                                    */
/*  DATE      = 2015/01/30 by songbb                               */
/*******************************************************************/

#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>

#include "frcomm.h"
#include "frstr.h"
#include "frmem.h"
#include "frhash2.h"
#include "frlog.h"

#include "conntrack.h"
#include "frct_comm.h"

#include "../../ora_core.h"
#include "../../comm/ora_comm.h"
#include "../../comm/ora_stmt.h"
#include "../../comm/ora_util.h"
#include "../ora_mar_engine.h"
#include "ora_ttc7_item.h"

/*******************************************************************************
*  FUNC     :  解析namedtype类型的字段
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_curr_sess                      (当前会话结构体)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_metadata                       (meta信息)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ora_ttc7_item_unmarshal_namedtype(Conntrack *p_st_conn
                                                    , L7session_ora *p_st_sess
                                                    , L7_ora_curr_session *p_st_curr_sess
                                                    , L7_ora_packet *p_st_ora_packet
                                                    , Sql_metadata_info *p_st_metadata)
{
    char c_tmp = 0;
    int i_tmp = 0;
    long long ll_tmp = 0LL;

    if (p_st_metadata->i_isuseless == FR_YES || p_st_metadata->i_isnullbydescribe == FR_YES)
        goto success;

    if (ora_mar_skipDALC(p_st_sess, p_st_ora_packet) != FR_SUCC) // arrayOfByte1
        goto error;
    if (ora_mar_skipDALC(p_st_sess, p_st_ora_packet) != FR_SUCC) // arrayOfByte2
        goto error;
    if (ora_mar_skipDALC(p_st_sess, p_st_ora_packet) != FR_SUCC) // arrayOfByte3
        goto error;

    if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // i
        goto error;

    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // l
        goto error;

    if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // j
        goto error;

    if (ll_tmp > 0LL)
    {
        if (ora_mar_skipCLR(p_st_sess, p_st_ora_packet) != FR_SUCC)
            goto error;
    }

    if (p_st_sess->i_use_special_field == FR_NO)
    {
        if (ora_mar_unmarshalSB1(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)
            goto error;
    }

success:
    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  直接跳过单个的column请求数据
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_metadata                       (meta信息)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc7_item_skip_req(Conntrack *p_st_conn
                        , L7session_ora *p_st_sess
                        , L7_ora_packet *p_st_ora_packet
                        , Sql_metadata_info *p_st_metadata)
{
    ORA_PRINT_INFO("ora_ttc7_item_unmarshal_req\n");
    int i_tmp = 0;

    if ((p_st_metadata->i_data_type == ORA_DTY_CLOB ||
            p_st_metadata->i_data_type == ORA_DTY_BLOB ||
            p_st_metadata->i_data_type == ORA_DTY_BFILE) && p_st_sess->c_pro_srv_version >= 6)
    {
        if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // k
            goto error;
        if (i_tmp == 0)
            return FR_SUCC;
    }

    if (ora_mar_skipCLR(p_st_sess, p_st_ora_packet) != FR_SUCC)
        goto error;

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  解析单个的column请求数据
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_metadata                       (meta信息)
*           :  **pp_bind_binary_value               (解析完成的数据内容)
*           :  *p_i_bind_value_len                  (解析完成的数据长度)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc7_item_unmarshal_req(Conntrack *p_st_conn
                                , L7session_ora *p_st_sess
                                , L7_ora_packet *p_st_ora_packet
                                , Sql_metadata_info *p_st_metadata
                                , char **pp_bind_binary_value
                                , int *p_i_bind_value_len)
{
    ORA_PRINT_INFO("ora_ttc7_item_unmarshal_req\n");
    int i_tmp = 0;

    if (p_st_metadata->s_ora_oacflg == 0x07)
        return FR_SUCC;

    if ((p_st_metadata->i_data_type == ORA_DTY_CLOB ||
            p_st_metadata->i_data_type == ORA_DTY_BLOB ||
            p_st_metadata->i_data_type == ORA_DTY_BFILE) && p_st_sess->c_pro_srv_version >= 6)
    {
        if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // k
            goto error;
        if (i_tmp == 0)
            return FR_SUCC;
    }

    if (ora_mar_unmarshalCLR_ttc(p_st_ora_packet, pp_bind_binary_value, p_i_bind_value_len) != FR_SUCC)
        goto error;

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  解析ttc7的字段数据
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_curr_sess                      (当前会话结构体)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_metadata                       (meta信息)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc7_item_unmarshal_resp(Conntrack *p_st_conn
                                , L7session_ora *p_st_sess
                                , L7_ora_curr_session *p_st_curr_sess
                                , L7_ora_packet *p_st_ora_packet
                                , Sql_metadata_info *p_st_metadata)
{
    ORA_PRINT_INFO("ora_ttc7_item_unmarshal_resp\n");
    char c_tmp = 0;
    short s_tmp = 0;
    int i_tmp = 0;
    long long ll_tmp = 0LL;

    if (p_st_metadata->i_data_type == ORA_DTY_NAMED_TYPE)
        return __ora_ttc7_item_unmarshal_namedtype(p_st_conn, p_st_sess, p_st_curr_sess, p_st_ora_packet, p_st_metadata);

    if (p_st_metadata->i_isuseless == FR_YES)
        return FR_SUCC;

    if (p_st_metadata->s_ora_oacflg == 0x07)
        return FR_SUCC;

    if ((p_st_metadata->i_data_type == ORA_DTY_CLOB ||
            p_st_metadata->i_data_type == ORA_DTY_BLOB ||
            p_st_metadata->i_data_type == ORA_DTY_BFILE) && p_st_sess->c_pro_srv_version >= 6)
    {
        if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // k
            goto error;
        if (i_tmp == 0)
        {
            if (ora_mar_unmarshalSB2(p_st_sess, p_st_ora_packet, &s_tmp) != FR_SUCC)
                goto error;
            return FR_SUCC;
        }
    }

    /**
    * TODO: 需要确定max_out_size的值
    */
//    if (this.max_out_size == 0) {
//        this.is_null = true;
//        return;
//    }

    if (ora_mar_skipCLR(p_st_sess, p_st_ora_packet) != FR_SUCC)
        goto error;

    ORA_PRINT_CRIT("i_iov_processed_flag:[%s]\n", FR_YESNO2STR(p_st_curr_sess->i_iov_processed_flag));
    if (p_st_curr_sess->i_rxh_processed_flag == FR_YES)
    {
        if (p_st_metadata->s_ora_oacflg == 0x01 || p_st_metadata->s_ora_oacflg == 0x03)
        {
            if (ora_mar_skip(p_st_ora_packet, 2) != FR_SUCC)
                goto error;
        }
        else if (p_st_metadata->i_data_type == ORA_DTY_LONG)
        {
            if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                goto error;
        }
    }

    if (p_st_sess->i_use_oci == FR_NO && p_st_sess->i_use_special_field == FR_NO)
    {
        if (ora_mar_unmarshalSB1(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC)
            goto error;

        if (p_st_curr_sess->i_rxh_processed_flag == FR_YES && p_st_metadata->i_data_type == ORA_DTY_LONG)
        {
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)
                goto error;
        }
    }

    return FR_SUCC;
error:
    return FR_FAIL;
}
